package com.jsg.sl651.message.parser;

import com.jsg.sl651.constant.EncodingElementIdentifier;
import com.jsg.sl651.entity.data.Element;
import com.jsg.sl651.enums.CommunicationMessageType;
import com.jsg.sl651.exception.ParserDataElementException;

/**
 * 具体某个字段的解析器
 */
public interface Parser<T> {

    /**
     * 根据指定的通信消息类型解析字节数组为数据对象。
     *
     * <p>方法核心</p>
     * <ul>
     *     <li>根据传入的通信消息类型（HEX 或 ASCII）选择不同的解析实现。</li>
     *     <li>调用对应的解析实现方法（parserHexImpl 或 parserAsciiImpl）完成具体解析逻辑。</li>
     *     <li>如果解析过程中发生异常，抛出自定义异常 ParserDataElementException。</li>
     *     <li>如果传入的通信消息类型未知，同样抛出 ParserDataElementException。</li>
     * </ul>
     *
     * @param encodingElement 数据类型定义 {@link EncodingElementIdentifier.EncodingElement}
     * @param type  通信消息类型，枚举值 {@link CommunicationMessageType}
     * @param bytes 待解析的字节数组
     * @return 解析成功后生成的数据对象 {@link Element}
     * @throws ParserDataElementException 如果解析失败或类型未知时抛出的异常
     */
    default Element<T> parser(EncodingElementIdentifier.EncodingElement encodingElement, CommunicationMessageType type, byte[] bytes) throws ParserDataElementException {
        if (type == CommunicationMessageType.HEX) {
            try {
                return parserHexImpl(encodingElement,bytes);
            } catch (Exception e) {
                throw new ParserDataElementException("解析数据异常:{}", e.getMessage());
            }
        } else if (type == CommunicationMessageType.ASCII){
            try {
                return parserAsciiImpl(encodingElement,bytes);
            } catch (Exception e) {
                throw new ParserDataElementException("解析数据异常:{}", e.getMessage());
            }
        } else {
            throw new ParserDataElementException("解析数据异常:{}", "未知的解析类型");
        }
    }

    /**
     * 解析Hex模式下的数据
     * <p>方法核心</p>
     * <ul>
     *     <li>解析该字节数组</li>
     *     <li>数据生成相应的数据对象{@link CommunicationMessageType}</li>
     * </ul>
     * @param element 数据类型定义 {@link EncodingElementIdentifier.EncodingElement}
     * @param bytes 字节数组
     * @return 解析出来的数据对象
     */
    public abstract Element<T> parserHexImpl(EncodingElementIdentifier.EncodingElement element,byte[] bytes) throws Exception;

    /**
     * 解析Hex模式下的数据
     * <p>方法核心</p>
     * <ul>
     *     <li>解析该字节数组</li>
     *     <li>数据生成相应的数据对象{@link CommunicationMessageType}</li>
     * </ul>
     * @param element 数据类型定义 {@link EncodingElementIdentifier.EncodingElement}
     * @param bytes 字节数组
     * @return 解析出来的数据对象
     */
    public abstract Element<T> parserAsciiImpl(EncodingElementIdentifier.EncodingElement element, byte[] bytes) throws Exception;


    default String bytesToString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append((char) b);
        }
        return sb.toString().trim();
    }
}
